<template>
  <div class="editor-input-border">
    <template v-if="mode === 'DESIGN'">
      <Toolbar class="editor-input-border" :editor="editorDesignInstance" :defaultConfig="toolbarConfig" :mode="editorModel" />
      <Editor
        style="height: 500px; overflow-y: hidden"
        :defaultConfig="editorConfig"
        :mode="editorModel"
        @onCreated="editorDesignCreated"
      />
    </template>
    <template v-else>
      <Toolbar class="editor-input-border" :editor="editorInstance" :defaultConfig="toolbarConfig" :mode="editorModel" />
      <Editor
        style="height: 500px; overflow-y: hidden"
        :defaultConfig="editorConfig"
        v-model.trim="_value"
        :mode="editorModel"
        @onChange="editorChange"
        @onCreated="editorCreated"
      />
    </template>
  </div>
</template>

<script setup lang="ts">
import { computed, onUnmounted, ref, useAttrs } from "vue";
import { isEmpty } from "lodash";
import { Editor, Toolbar } from "@wangeditor/editor-for-vue";
import "@wangeditor/editor/dist/css/style.css";
import useMultipartOssStore from "@/stores/modules/multipartOssStore";
import { createNewFilename } from "@/utils/upload";

const attrs = useAttrs();
const props = defineProps({
  mode: {
    type: String,
    default: "DESIGN"
  },
  required: {
    type: Boolean,
    default: false
  },
  readonly: {
    type: Boolean,
    default: false
  },
  modelValue: {
    type: String,
    default: ""
  },
  placeholder: {
    type: String,
    default: "请输入内容"
  }
});
const emit = defineEmits(["update:modelValue"]);
const multipartOssStore = useMultipartOssStore();

const _value = computed({
  get() {
    return props.modelValue;
  },
  set(val) {
    emit("update:modelValue", val);
  }
});

const editorInstance = ref<any>(null);
const editorDesignInstance = ref<any>(null);
const toolbarConfig = ref({
  excludeKeys: ["insertImage", "insertVideo", "uploadVideo", "editVideoSize", "|", "fullScreen"]
});

const editorConfig = ref({
  placeholder: "请输入内容...",
  readOnly: false,
  MENU_CONF: {
    uploadImage: {
      customUpload: async (file: any, insertFn: any) => {
        try {
          const { file: fileData, objectName } = await createNewFilename(file);
          await multipartOssStore.submit(objectName, fileData, file.uid);
          await multipartOssStore.setACL(objectName, "public-read");
          const fileUrl = await multipartOssStore.signatureUrl(objectName);
          const url = fileUrl ? `${fileUrl}`.split("?")[0] : "";
          insertFn(url, "", url);
        } catch (err) {
          console.log(err);
          alert(JSON.stringify(err));
        }
      }
    }
  }
});
const editorModel = ref("default");

const editorCreated = (editor: any) => {
  editorInstance.value = Object.seal(editor);
  attrs.disabled && disableEditor();
};
const getText = (str: string) => {
  return str
    .replace(/<[^<p>]+>/g, "")
    .replace(/<[</p>$]+>/g, "")
    .replace(/&nbsp;/gi, "")
    .replace(/<[^<br/>]+>/g, "");
};
const editorChange = () => {
  const val = editorInstance.value.getHtml();
  const text = getText(val);
  emit("update:modelValue", !text ? "" : val);
};
const disableEditor = () => {
  editorInstance.value.disable();
};
const editorDesignCreated = (editor: any) => {
  editorDesignInstance.value = Object.seal(editor);
  disableDesignEditor();
};
const disableDesignEditor = () => {
  editorDesignInstance.value.disable();
};

onUnmounted(() => {
  const editor = editorInstance.value;
  editor && editor.destroy();
});

if (isEmpty(_value.value) && !attrs.disabled) {
  _value.value = attrs.defaultValue as any;
}
</script>

<style lang="less">
.editor-input-border {
  width: 100%;
  border: 1px solid #ccc;
}

button[data-menu-key="group-video"] {
  display: none;
}
</style>
